/**
 *  Serponix is an arcade game in focus to multiplayer based on the classic game Snake.
 *  Copyright (C) 2010 - 2011  Daniel Vala
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License,
 *  or  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  If you have any question do not hesitate to contact author
 *  on e-mail address: danielvala42@gmail.com
 */
package com.serponix.gui.settings;

import com.serponix.settings.SettingsFactory;
import com.serponix.settings.SnakeAction;
import com.serponix.gui.MainPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.util.Observable;
import java.util.Observer;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;

/**
 * View obsahuje všechny komponenty GUI pro zobrazení nastavení kláves,
 * jmen hráčů, počtu hráčů, čísla portu a tlačítek pro uložení, storno a default.
 * @author Daniel Vala
 */
public class ViewNastaveni extends JPanel implements Observer {

    private ModelNastaveni model;
    private JPanel panel;
    private JButton[][] buttony;
    private JTextField[] textFieldsJmena;
    private JSpinner spinnerPocetHracu, spinnerPort;
    private SnakeAction[] klavesy = {SnakeAction.UP, SnakeAction.DOWN, SnakeAction.LEFT, SnakeAction.RIGHT, SnakeAction.FIRE, SnakeAction.FIRE2};
    private JButton ulozitButton, vychoziButton, stornoButton;
    private final int POCET_HRACU = 4;

    public ViewNastaveni(ModelNastaveni model, MainPanel okno) {
        this.model = model;
        buttony = new JButton[POCET_HRACU][6];
        panel = new JPanel(new BorderLayout(30, 30));

        JPanel panelVsechOvladani = new JPanel(new GridLayout(4, 1, 0, 50));
        textFieldsJmena = new JTextField[POCET_HRACU];
        for (int i = 0; i < POCET_HRACU; i++) {
            panelVsechOvladani.add(vytvorPanelOvladani(i));
        }
        panel.add(panelVsechOvladani, BorderLayout.NORTH);


        JPanel panelDalsihoNastaveni = new JPanel();


        panelDalsihoNastaveni.add(new JLabel("počet hráčů"));

        spinnerPocetHracu = new JSpinner(new SpinnerNumberModel(2, 1, 4, 1));
        spinnerPocetHracu.setValue(SettingsFactory.getNastaveniHry().getPocetHracu());
        spinnerPocetHracu.addChangeListener(new SetPocetHracuController(this));
        panelDalsihoNastaveni.add(spinnerPocetHracu);

        panelDalsihoNastaveni.add(new JLabel("port"));
        spinnerPort = new JSpinner(new SpinnerNumberModel(SettingsFactory.getNastaveniHry().getPort(), 1, 65535, 1));
        panelDalsihoNastaveni.add(spinnerPort);

        JButton napovedaPort = new JButton("?");
        napovedaPort.addActionListener(new ControllerNapovedaPort(this));
        panelDalsihoNastaveni.add(napovedaPort);

        panel.add(panelDalsihoNastaveni, BorderLayout.CENTER);

        JPanel panelPotvrzeni = new JPanel();
        vychoziButton = new JButton("Výchozí");
        vychoziButton.addActionListener(new SetDefaultController(model));
        panelPotvrzeni.add(vychoziButton);

        ulozitButton = new JButton("Uložit");
        ulozitButton.addActionListener(new ControllerSave(model, this, okno));
        panelPotvrzeni.add(ulozitButton);

        stornoButton = new JButton("Storno");
        stornoButton.addActionListener(new MenuController(okno));
        panelPotvrzeni.add(stornoButton);

        panel.add(panelPotvrzeni, BorderLayout.SOUTH);

        add(panel);

        setPocetEditovatelnychJmen(SettingsFactory.getNastaveniHry().getPocetHracu());
        model.addObserver(this);
    }

    /**
     * Nastaví editovatelné jména a tlačítka pro nastavení kláves zadanému počtu hráčů.
     * @param pocet Pocet hráčů, kteří si budou moci nastavit své ovládání.
     */
    public void setPocetEditovatelnychJmen(int pocet) {
        if (pocet < 1 || pocet > POCET_HRACU) {
            return;
        }
        for (int i = 0; i < pocet; i++) {
            textFieldsJmena[i].setEnabled(true);
            for (int j = 0; j < 6; j++) {
                buttony[i][j].setEnabled(true);
            }
        }
        for (int i = pocet; i < 4; i++) {
            textFieldsJmena[i].setEnabled(false);
            for (int j = 0; j < 6; j++) {
                buttony[i][j].setEnabled(false);
            }
        }
    }

    public String getTextFieldJmeno(int i) {
        return textFieldsJmena[i].getText();
    }

    public int getPocetHracu() {
        return (Integer) spinnerPocetHracu.getValue();
    }

    public int getPort() {
        return (Integer) spinnerPort.getValue();
    }

    private JPanel vytvorPanelOvladani(int hrac) {
        JPanel panelKlaves = new JPanel(new GridLayout(2, 8));

        textFieldsJmena[hrac] = new JTextField(SettingsFactory.getNastaveniHry().getJmeno(hrac), 7);

        for (int i = 0; i < klavesy.length; i++) {
            buttony[hrac][i] = new MyButton(KeyEvent.getKeyText(model.getKlavesy(hrac).get(klavesy[i])));
            buttony[hrac][i].addKeyListener(new KeyController(model, buttony[hrac][i], hrac, klavesy[i]));
        }

        panelKlaves.add(new JPanel());
        panelKlaves.add(new JPanel());
        panelKlaves.add(new JPanel());
        panelKlaves.add(buttony[hrac][0]);
        panelKlaves.add(new JPanel());
        panelKlaves.add(new JPanel());
        panelKlaves.add(buttony[hrac][4]);
        panelKlaves.add(new JLabel("laser"));

        // nový řádek
        panelKlaves.add(textFieldsJmena[hrac]);
        panelKlaves.add(new JPanel());
        panelKlaves.add(buttony[hrac][2]);
        panelKlaves.add(buttony[hrac][1]);
        panelKlaves.add(buttony[hrac][3]);
        panelKlaves.add(new JPanel());
        panelKlaves.add(buttony[hrac][5]);
        panelKlaves.add(new JLabel("raketa"));

        return panelKlaves;
    }

    @Override
    public void update(Observable o, Object arg) {
        for (int j = 0; j < buttony.length; j++) {
            for (int i = 0; i < buttony[j].length; i++) {
                buttony[j][i].setText(KeyEvent.getKeyText(model.getKlavesy(j).get(klavesy[i])));
            }
        }
        for (int i = 0; i < textFieldsJmena.length; i++) {
            textFieldsJmena[i].setText(SettingsFactory.getNastaveniHry().getJmeno(i));
        }
        setPocetEditovatelnychJmen(SettingsFactory.getNastaveniHry().getPocetHracu());
        spinnerPocetHracu.setValue(SettingsFactory.getNastaveniHry().getPocetHracu());
        spinnerPort.setValue(SettingsFactory.getNastaveniHry().getPort());
    }

    /**
     * Třída mění velikost standardního tlačítka na šířku 100.
     */
    private static class MyButton extends JButton {

        public MyButton(String text, Icon icon) {
            super(text, icon);
        }

        public MyButton(Action a) {
            super(a);
        }

        public MyButton(String text) {
            super(text);
        }

        public MyButton(Icon icon) {
            super(icon);
        }

        public MyButton() {
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension d = super.getPreferredSize();
            d.width = 100;
            return d;
        }
    }
}
